#include "eval.h"

Object*
quote (List* args)
{
  cout << "quote " << args->toString () << endl;
  if (args->empty ())
    return new Error ("requires a *single* argument");
  return (*args)[0];
}

Object*
eval (Object* item, List* environment)
{
  if (item->type () == "Symbol")
    return new List ();
  if (item->type () == "List")
    return eval ((List*)item, environment);
  return item;
}

Object*
eval (List* expr, List* environment)
{
  Object* result = new Object ();
  if ((*expr)[0]->type () == "Symbol")
    {
      Symbol *sym = (Symbol*)(*expr)[0];
      cout << "eval->first->symbol = " << sym->toString () << endl;
      List *args = new List ();
      expr->remove (0);
      cout << "expr->remove (0): " << expr->toString () << endl;
      if (*sym == "quote")
	return quote (expr);

      result = eval (sym, environment);
      Object* item = 0;
      // Loop through list
      for (listIter i = expr->begin ();
	   i != expr->end () && result->type () != "Error";
	   i++)
	{
	  item = eval (*i, environment);
	  if (item->type () == "Error")
	    {
	      Error* temp = (Error*)item;
	      return new Error (string("Argument returned an error; cannot continue eval'ing\n") + indent () + string(" ") + temp->toString (), sym->name, args);
	    }
	  args->append (item);

	  if (result->type () == "CFunction")
	    result = new Error ("Implement CFunction class");
	  else
	    result = new Error ("is NOT a function");
	}
      if (result->type () == "Error")
	{
	  Error* temp = (Error*)result;
	  temp->function = sym->name;
	  temp->args = args;
	  return temp;
	}
      cout << "args: " << args->toString () << endl;
    }
  return result;
}
